



-- If the number or color values are floating point values then this function performs approximative 如果数字或颜色值是浮点值，则此函数执行近似值比较， 
-- comparison, otherwise a typical (strict) comparison is performed. 否则执行典型（严格）比较。 
-- 
-- Both input values are expected to be the same type (checked by an assert). 两个输入值应为同一类型（由断言检查）。 
fn approxEq numberOrColor0 numberOrColor1 epsilon:1e-6 =(  

	-- 如果numberOrColor0是数字类型 numberOrColor1 必须也是数字类型        
	if ((classof numberOrColor0) == integer) or ((classof numberOrColor0) == float) then (  
		assert ((classof numberOrColor1) == integer or (classof numberOrColor1) == float)  
	)  
	-- numberOrColor0 numberOrColor1 其中一个是浮点类型         
	if ((classof numberOrColor0) == float) or ((classof numberOrColor1) == float) then (  
		-- 返回 numberOrColor0 numberOrColor1 这两个值是不是相等        
		/*return*/ abs (numberOrColor0 - numberOrColor1) <= epsilon  
	) else (  
		--断言 numberOrColor0 numberOrColor1 两个类型相等        
		assert ((classof numberOrColor0) == (classof numberOrColor1))  


		-- numberOrColor0 是整数类型         
		if (classof numberOrColor0 == integer) then (  
			 
			/*return*/ numberOrColor0 == numberOrColor1  
		) else (  
			-- numberOrColor0 是颜色类型        
			assert ((classof numberOrColor0) == color)  

			-- Round all the components and cast them to int, since they are presented to user as ints,        
			-- however they are internally represented as floats, which may lead to inaccurate        
			-- comparisons.        

			--如果两个颜色的rgb 值分别不超过1 则认为相等         
			local r0 = int(round numberOrColor0.r)  
			local g0 = int(round numberOrColor0.g)  
			local b0 = int(round numberOrColor0.b)  

			local r1 = int(round numberOrColor1.r)  
			local g1 = int(round numberOrColor1.g)  
			local b1 = int(round numberOrColor1.b)  

			/*return*/ (r0 == r1) and (g0 == g1) and (b0 == b1)  
		)  
	) 
) 


-- Converts color with values in range [0, 255] to its average luminance in range [0, 255]. 将值在 [0， 255] 范围内的颜色转换为范围 [0， 255] 中的平均亮度 
fn colorToAverageLuminance inputColor =(  
	/*return*/ ((inputColor.r + inputColor.g + inputColor.b) as float) / 3.0 
)



--判断输入贴图是否表示法线贴图。 
fn isNormalMap inputMap =(  
	local inputMapClass = classof inputMap  

	--  返回inputMapClass是否是 VrayNormalMap or CoronaNormal or Normal_Bump中的一种       
	/*return*/ inputMapClass == VrayNormalMap or inputMapClass == CoronaNormal or inputMapClass == Normal_Bump 
) 



--判断贴图是否激活 根据贴图是否是undefined   贴图是否开启  贴图的使用率是否大于0 
fn mapIsActive map mapEnabled mapContribution =(  
	/*return*/ map != undefined and mapEnabled and mapContribution > 0.0 
) 

-- 判断是否使用材质的某个属性  比如半透明属性Fraction 
fn usesLobeCoronaMtl paramLevel paramTexmap paramTexmapOn paramMapAmount paramColor =(  
	if paramLevel > 0.0 then (  
		if mapIsActive paramTexmap paramTexmapOn paramMapAmount then (  
			/*return*/ true  
		) else (  
			/*return*/ paramColor != black  
		)  
	) else (  
		/*return*/ false  
	) 
) 

-- 销毁插件面板                    
fn closeGui title= (  
	try(  
		windows.sendMessage (windows.getChildHWND 0 title parent:#max)[1] 0x0010 0 0  
	)catch()   
	
) 


--@fn Debounce：防抖 在_time时间范围内重复执行都只执行最后一次 
--@params callback：要执行的回调函数 
--@params _time：延时执行的时间 默认500ms 
struct Debounce ( 
	callback, 
	_time = 500 , 
	theTimer = undefined, 
	fn fun = ( 
		this.theTimer.stop()  
		this.theTimer = undefined 
		this.callback()   

	), 
	fn execute = ( 
		if(this.theTimer!=undefined)then( 
			this.theTimer.stop()  
			this.theTimer = undefined 
		)  
		this.theTimer = dotNetObject "System.Windows.Forms.Timer" 
		this.theTimer.interval = this._time 
		dotnet.addEventHandler this.theTimer "tick" this.fun  
		theTimer.start()  
	) 
)

--@fn ThreadDoWork： 创建一个线程执行传递过来的函数
--@params method：子线程要执行的函数
fn ThreadDoWork method =
(
	MainThread = dotNetObject "System.ComponentModel.BackgroundWorker" --线程对象
	dotNet.addEventHandler MainThread "DoWork" method	
	MainThread.RunWorkerAsync()
)
